﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "serialmanager.h"
#include "connetionsttings.h"


MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //率先创建对象
    serialPort = new serialManager;
    connectionDialog = new ConnetionSttings(this);
    cylinderSpeed = new cylinderspeed;
    //槽函数连接集合
    connectSignal2Slots();
    //图标初始化
    chartsInit();
    //液压控制界面
    cylinderControl();
    //开关阀单点控制界面
    hyvlavecontrol();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slotopenConnectionDialog()
{
    connectionDialog->setModal(true);
    connectionDialog->exec();
}

void MainWindow::connectSignal2Slots()
{
    //打开设置函数
    connect(ui->portConnnect, &QAction::triggered, this, &MainWindow::slotopenConnectionDialog);
    //设置并打开关闭串口
    connect(connectionDialog, &ConnetionSttings::signalSerialConfigUpdatad, serialPort, &serialManager::openSerialPort);
    connect(connectionDialog, &ConnetionSttings::signalSerialConfigStop, serialPort, &serialManager::stopSerialPort);
    //串口状态
    connect(serialPort, &serialManager::sigserialOpen, this, &MainWindow::slotDispalyMessage);
    connect(serialPort, &serialManager::sigserialClose, this, &MainWindow::slotDispalyMessage);
    connect(serialPort, &serialManager::sigerrorOccured, this, &MainWindow::slotDispalyMessage);
    //液压缸速度处理和显示槽函数
    connect(serialPort, &serialManager::sigdataReceive, cylinderSpeed, &cylinderspeed::slotSpeedInfoHandle);
    connect(cylinderSpeed, &cylinderspeed::sigSpeedvalue, this, [ = ](double speed)
    {
        qDebug() << "数据采集被启动";
        QString speedText = QString::number(speed) + QString("mm/s"); // 转换为保留两位小数的字符串
        ui->cylinderSpeed_R->setText(speedText);

        //更新图表
        // 将新的速度值添加到曲线图中
        static int timeCounter = 0;  // 保持时间计数器
        // cylinderSpeedLineSeries->append(timeCounter++, speed);  // 将新的速度值添加到曲线图中

        // // 可选：如果数据点超出 X 轴最大范围，更新 X 轴范围
        // if (timeCounter > cylinderSpeedaxisX->max())
        // {
        //     cylinderSpeedaxisX->setMax(timeCounter);  // 增加 X 轴最大值
        // }

        // // 更新 Y 轴的范围（可选）
        // if (speed > cylinderSpeedaxisY->max())
        // {
        //     cylinderSpeedaxisY->setMax(speed + 10);
        // }
        // else if (speed < cylinderSpeedaxisY->min())
        // {
        //     cylinderSpeedaxisY->setMin(speed - 10);
        // }
        // 更新图表
        // 更新图表
        static const int MAX_VISIBLE_POINTS = 100; // 只保留最近 100 个点
        static QList<QPointF> speedData;  // 存储数据点

        // 添加新的速度数据
        speedData.append(QPointF(timeCounter++, speed));

        // 只保留最近 MAX_VISIBLE_POINTS 个点
        if (speedData.size() > MAX_VISIBLE_POINTS)
        {
            speedData.removeFirst();
        }

        // 更新曲线数据
        cylinderSpeedLineSeries->replace(speedData);

        // 更新 X 轴范围
        if (!speedData.isEmpty())
        {
            cylinderSpeedaxisX->setRange(speedData.first().x(), speedData.last().x());
        }

        // 计算当前数据范围
        double minSpeed = speedData.first().y();
        double maxSpeed = speedData.first().y();
        for (const auto& point : speedData)
        {
            if (point.y() < minSpeed) minSpeed = point.y();
            if (point.y() > maxSpeed) maxSpeed = point.y();
        }

        // **改进 Y 轴逻辑**
        if (minSpeed > 0)
            minSpeed = 0;  // 确保最小值不高于 0，防止 0 速度的曲线消失

        double margin = (maxSpeed - minSpeed) * 0.1; // 添加 10% 的额外空间
        if (margin < 1) margin = 1; // 避免 margin 过小导致 Y 轴不变化

        cylinderSpeedaxisY->setRange(minSpeed, maxSpeed + margin);

    });
}


void MainWindow::chartsInit()
{
    //液压缸图表初始化(现在的图标还是太小了，进一步优化)
    cylinderSpeedChart = new QChart();
    cylinderSpeedLineSeries = new QLineSeries();
    cylinderSpeedLineSeries->setName("RealSpeed");
    cylinderSpeedaxisX = new QValueAxis();
    cylinderSpeedaxisY = new QValueAxis();
    // cylinderSpeedChart->setTitle("Cylinder Speed");
    cylinderSpeedChart->addSeries(cylinderSpeedLineSeries);

    // 设置 X 和 Y 轴
    cylinderSpeedaxisX->setRange(0, 100);  // 根据时间范围或数据调整X轴范围
    cylinderSpeedaxisY->setRange(-100, 100);  // 根据预期的速度值调整Y轴范围

    cylinderSpeedChart->setAxisX(cylinderSpeedaxisX, cylinderSpeedLineSeries);
    cylinderSpeedChart->setAxisY(cylinderSpeedaxisY, cylinderSpeedLineSeries);

    // 在QChartView 并显示
    ui->cylinderSpeedChart->setChart(cylinderSpeedChart);
    ui->cylinderSpeedChart->setRenderHint(QPainter::Antialiasing);//设置抗锯齿
    cylinderSpeedChart->setMargins(QMargins(0, 0, 0, 0));//尽量让表格充满整个view区域




    //前后高低压蓄能器图表


    //四腔室液压显示图表
}


//液压缸速度控制界面函数
void MainWindow::cylinderControl()
{
    //将连个radiobutton进行互斥
    auto* buttonGroup = new QButtonGroup;
    buttonGroup->addButton(ui->normalCheck);
    buttonGroup->addButton(ui->sineCheck);
    buttonGroup->setExclusive(true);
    //默认初始状态
    ui->normalCheck->setChecked(true);
    //这里是带有参数的进行传递，非常的麻烦。需要老写法
    connect(buttonGroup, QOverload<QAbstractButton*>::of(&QButtonGroup::buttonClicked), this, [ = ](QAbstractButton*)
    {
        bool state1 = ui->normalCheck->isChecked();
        ui->horizontalSlider_speed->setEnabled(state1);
        ui->spinBox_speed->setEnabled(state1);

        bool state2 = ui->sineCheck->isChecked();
        ui->spinBox_Ampt->setEnabled(state2);
        ui->spinBox_Freq->setEnabled(state2);
    });

    //连接信号槽后模拟触发一次，保证初始化正确
    QMetaObject::invokeMethod(this, [ = ]()
    {
        ui->normalCheck->click();
    }, Qt::QueuedConnection);


    //绑定slider和spinbox
    ui->horizontalSlider_speed->setRange(-100, 100);
    ui->spinBox_speed->setRange(-100, 100);
    connect(ui->horizontalSlider_speed, &QSlider::valueChanged, ui->spinBox_speed, &QSpinBox::setValue);
    connect(ui->spinBox_speed, QOverload<int>::of(&QSpinBox::valueChanged), ui->horizontalSlider_speed, &QSlider::setValue);

    //加上一个单位
    ui->spinBox_speed->setSuffix("mm/s");

    //设置正弦函数的处理逻辑

}

//开关阀控制组件初始化
void MainWindow::hyvlavecontrol()
{

    auto bindSliderSpinbox = [](QSlider * slider, QSpinBox * spinbox)
    {
        slider->setRange(0, 100);
        spinbox->setRange(0, 100);

        // 同步初值
        spinbox->setValue(slider->value());

        QObject::connect(slider, &QSlider::valueChanged, spinbox, &QSpinBox::setValue);
        QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), slider, &QSlider::setValue);

        // 单位显示（SpinBox右侧加单位）
        spinbox->setSuffix("%");
    };

    QVector<QSlider*> sliders = {ui->horizontalSlider_HA, ui->horizontalSlider_HB, ui->horizontalSlider_HC,
                                 ui->horizontalSlider_HD, ui->horizontalSlider_LA, ui->horizontalSlider_LB,
                                 ui->horizontalSlider_LC, ui->horizontalSlider_LD
                                };
    QVector<QSpinBox*> spinboxes = {ui->spinBox_HA, ui->spinBox_HB, ui->spinBox_HC, ui->spinBox_HD, ui->spinBox_LA,
                                    ui->spinBox_LB, ui->spinBox_LC, ui->spinBox_LD
                                   };

    for (int i = 0; i < sliders.size(); ++i)
    {
        bindSliderSpinbox(sliders[i], spinboxes[i]);
    }

    //确认开关阀的单点控制执行
    ui->applyButton_HC->setEnabled(false);
    connect(ui->checkBox, &QCheckBox::toggled, ui->applyButton_HC, &QPushButton::setEnabled);
}


//信息显示函
void MainWindow::slotDispalyMessage(const QString& message)
{
    ui->logsText->append(message);
}


